﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WeChat;
using WeChat.Events;
using WeChat.Helper;
namespace WeChatRobot
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private int pid;

        private WeChatSdk WeChat;
        public delegate void ShowLogDelegate(string msg);
        public ShowLogDelegate ShowLogEvent;

        public List<ContactModel> Contacts { get; set; }

        public ObservableCollection<MessageModel> Msgs { get; set; }
        public MainWindow()
        {
            InitializeComponent();
            WeChat = new WeChatSdk();
            Contacts = new List<ContactModel>();
            Msgs = new ObservableCollection<MessageModel>();
            DataContext = this;
            ShowLogEvent = (msg) =>
            {
                this.tb_Log.AppendText(msg);
                this.tb_Log.AppendText(Environment.NewLine);
                this.tb_Log.ScrollToEnd();
            };

            WeChat.LogEvent += WeChat_LogEvent;
            WeChat.ReceiveContactEvent += WeChat_ReceiveContactEvent;
            WeChat.ReceiveOtherIMEvent += WeChat_ReceiveOtherIMEvent;
            WeChat.WeChatInitEvent += WeChat_WeChatInitEvent;
            WeChat.ConnetionCloseEvent += WeChat_ConnetionCloseEvent;
            btn_OpenWeChat.Click += Btn_OpenWeChat_Click;
            btn_UserInfo.Click += btn_UserInfo_Click;
            Query.Click += Query_Click;


        }

        private void WeChat_ConnetionCloseEvent(object sender, WeChat.Events.ConnetionCloseArgs e)
        {
            ShowLog($"[日志]websocket连接断开,请检查微信是否正常运行。");
        }

        private void WeChat_WeChatInitEvent(object sender, WeChat.Events.WeChatInitArgs e)
        {
            pid = e.PorcessId;
            ShowLog($"[日志]{e.Message}");
            while (!WeChat.CheckLoginState(e.PorcessId))
            {
                Thread.Sleep(1000);
            }
            var user = WeChat.GetLoginUser(e.PorcessId);
            if (user != null)
            {
                this.Dispatcher.BeginInvoke((Action)delegate ()
                {
                    tb_UserInfo.Text = QNSerialize.SerializeObject(user);
                    lb_Status.Content = "已登录";
                });
            }
            this.Dispatcher.BeginInvoke((Action)delegate ()
            {
                Contacts.Clear();
            });
            WeChat.GetContactList(pid);
        }

        private void WeChat_ReceiveOtherIMEvent(object sender, WeChat.Events.ReceiveOtherIMArgs e)
        {
            if (e != null && e.Type == 1)
            {
                var model = new MessageModel()
                {
                    FromWxid = e.FromWxid,
                    SendWxid = e.SendWxid,
                    Content = e.Content,
                    Type = e.Type.ToString(),
                };
                this.Dispatcher.BeginInvoke((Action)delegate ()
                {
                    dg_ReceiveOtherIMArgs.Items.Add(model);
                });
            }
            ShowLog($"[消息]{e.Content}");
        }

        private void WeChat_ReceiveContactEvent(object sender, Contact e)
        {
            if (e != null)
            {
                var model = new ContactModel()
                {
                    Alias = e.Alias,
                    BigHeadImgUrl = e.BigHeadImgUrl,
                    NickName = e.NickName,
                    Remark = e.Remark,
                    UserName = e.UserName
                };

                this.Dispatcher.BeginInvoke((Action)delegate ()
                {
                    dg_Contacts.Items.Add(model);
                    Contacts.Add(model);
                });
            }
        }

        private void WeChat_LogEvent(object sender, string e)
        {
            ShowLog($"[日志]{e}");
        }

        private void Btn_OpenWeChat_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var ret = WeChat.OpenWechat();
                var list = Process.GetProcessesByName("WeChat");
                if (list.Length > 0)
                    ret = list[0].Id;
                if (ret == 0) return;
                if (!WeChat.IsInjected(ret))
                {
                    WeChat.InjectDll(pid);
                }
            }
            catch (Exception ex)
            {
                ShowLog($"[异常]{ex.Message}");
            }

        }


        public void ShowLog(string msg)
        {
            if (string.IsNullOrEmpty(msg))
            {
                return;
            }
            if (!msg.StartsWith(DateTime.Now.Year.ToString(CultureInfo.InvariantCulture)))
            {
                msg = string.Format("{0} {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msg);
            }
            msg = msg.Replace("\r\n", Environment.NewLine)
                .Replace("\n", Environment.NewLine)
                .Replace("\r", Environment.NewLine);
            this.Dispatcher.BeginInvoke(ShowLogEvent, msg);

        }

        /// <summary>
        /// 刷新联系人信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_UserInfo_Click(object sender, RoutedEventArgs e)
        {
            this.Dispatcher.BeginInvoke((Action)delegate ()
            {
                Contacts.Clear();
                WeChat.GetContactList(pid);
            });
           


        }
        /// <summary>
        /// 发送文本消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {

            WeChat.SendTextMessage(pid, tb_Param1.Text.Trim(), tb_Content.Text.Trim());
            
            //插入消息记录
            var model = new MessageModel()
            {
                FromWxid = "me",
                SendWxid = tb_Param1.Text.Trim(),
                Content = tb_Content.Text.Trim(),
                Type = "-1",
            };
            this.Dispatcher.BeginInvoke((Action)delegate ()
            {
                dg_ReceiveOtherIMArgs.Items.Add(model);
            });
            tb_Content.Text = "";
        }

        /// <summary>
        /// 设置当前选中的联系人--消息记录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dg_ReceiveOtherIMArgs_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //tb_Param1
            DataGrid dataGrid = sender as DataGrid;
            if (e.AddedItems != null && e.AddedItems.Count > 0)
            {
                // find row for the first selected item
                DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(e.AddedItems[0]);

                if (row != null)
                {
                    DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
                    // find grid cell object for the cell with index 0
                    DataGridCell username = presenter.ItemContainerGenerator.ContainerFromIndex(0) as DataGridCell;
                    if (username != null)
                    {
                        tb_Param1.Text = ((TextBlock)username.Content).Text;
                    }

                }
            }
        }

        /// <summary>
        /// 设置当前选中的联系人--联系人
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //tb_Param1
            DataGrid dataGrid = sender as DataGrid;
            if (e.AddedItems != null && e.AddedItems.Count > 0)
            {
                // find row for the first selected item
                DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(e.AddedItems[0]);

                if (row != null)
                {
                    DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
                    // find grid cell object for the cell with index 0
                    DataGridCell username = presenter.ItemContainerGenerator.ContainerFromIndex(0) as DataGridCell;
                    if (username != null)
                    {
                        tb_Param1.Text = ((TextBlock)username.Content).Text;
                    }
                    DataGridCell nickName = presenter.ItemContainerGenerator.ContainerFromIndex(1) as DataGridCell;
                    if (username != null)
                    {
                        tb_Param2.Text = ((TextBlock)nickName.Content).Text;
                    }
                    DataGridCell remark = presenter.ItemContainerGenerator.ContainerFromIndex(2) as DataGridCell;
                    if (username != null)
                    {
                        tb_Param2.Text += "-" + ((TextBlock)remark.Content).Text;
                    }
                }
            }
        }
        static T GetVisualChild<T>(Visual parent) where T : Visual
        {
            T child = default(T);
            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++)
            {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                child = v as T;
                if (child == null) child = GetVisualChild<T>(v);
                if (child != null) break;
            }
            return child;
        }
        /// <summary>
        /// 查询联系人
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Query_Click(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrEmpty(NickName.Text) && !string.IsNullOrEmpty(Remark.Text))
            {
                this.Dispatcher.BeginInvoke((Action)delegate ()
                {
                    var find = Contacts.AsQueryable().Where(c => c.NickName.Contains(NickName.Text) || c.Remark.Contains(Remark.Text));
                    dg_Contacts.Items.Clear();
                    foreach (var item in find)
                    {
                        dg_Contacts.Items.Add(item);
                    }
                });
            }
            else if (!string.IsNullOrEmpty(NickName.Text))
            {

                this.Dispatcher.BeginInvoke((Action)delegate ()
                {
                    var find = Contacts.AsQueryable().Where(c => c.NickName.Contains(NickName.Text));
                    dg_Contacts.Items.Clear();
                    foreach (var item in find)
                    {
                        dg_Contacts.Items.Add(item);
                    }

                });
            }
            else if (!string.IsNullOrEmpty(Remark.Text))
            {

                this.Dispatcher.BeginInvoke((Action)delegate ()
                {
                    var find = Contacts.AsQueryable().Where(c => c.Remark.Contains(Remark.Text));
                    dg_Contacts.Items.Clear();
                    foreach (var item in find)
                    {
                        dg_Contacts.Items.Add(item);
                    }

                });

            }

        }
    }

    #region 联系人
    public class ContactModel : INotifyPropertyChanged
    {
        private string userName;

        public string UserName
        {
            get { return userName; }
            set
            {
                if (userName != value)
                {
                    userName = value;
                    OnPropertyChanged("UserName");
                }
            }
        }

        public string Alias { get; set; }

        public string NickName { get; set; }

        public string Remark { get; set; }

        public string BigHeadImgUrl { get; set; }



        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
    #region 消息记录
    public class MessageModel : INotifyPropertyChanged
    {
        private string fromWxid;

        public string FromWxid
        {
            get { return fromWxid; }
            set
            {
                if (fromWxid != value)
                {
                    fromWxid = value;
                    OnPropertyChanged("FromWxid");
                }
            }
        }

        public string SendWxid { get; set; }

        public string Content { get; set; }

        public string Type { get; set; }



        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}
